library(tidyverse)
library(ggplot2)
library(plotly)
library(dplyr)
library(leaflet)
library(maps)
df <- read_csv('klapeye-global-terrorism.csv')
Rows: 27129 Columns: 9
-- Column specification -----------------------------------------------
Delimiter: ","
chr  (6): COUNTRY, REGION, PERPETRATOR, DESCRIPTION, COORDINATES, A...
dbl  (2): INJURED, DEAD
date (1): DATE

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.
df <- drop_na(df, INJURED)
df <- drop_na(df, DEAD)
head(df)
dim(df)
[1] 5799    9
Month_names = list("JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC")
Month_numbers = list(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)

df$YEAR <- as.numeric(format(df$DATE, "%Y"))
df$MONTH <- as.numeric(format(df$DATE, "%m"))
df$DAY <- as.numeric(format(df$DATE, "%d"))

class(df$COORDINATES)
[1] "character"
df <- df %>% separate(COORDINATES, c("LATITUDE", "LONGITUDE"), sep = ",")
plot1 <- df %>% count(YEAR) %>% rename(Count = n) %>% ggplot(aes(YEAR, Count)) + geom_line(color = "firebrick2") + geom_point(color = "firebrick2") + labs(title = "Number of terrorist atacks by year") + theme_light()

ggplotly(plot1)

The Plot given above uses ggplotly to interactively plot the number of terrorist attacks with the years that they took place in. The year 2006 had the highest number of terrorist attacks with the number of attacks being 914.

# Heat map
plot2 <- drop_na(df, `ATTACK TYPE`) %>% count(YEAR, `ATTACK TYPE`) %>% rename(Count = n) %>% mutate(`ATTACK TYPE` = reorder(`ATTACK TYPE`, Count)) %>% plot_ly(x = ~YEAR, y = ~`ATTACK TYPE`, z = ~Count, type = "heatmap")

plot2 <- plot2 %>% layout(title = "Terrorist Attacks time series by Type", yaxis = list(title = "Count"))
 
plot2

In the above plot Plotly is used to add a heat map that describes the number of attacks, the type of attacks and the years in which they took place. The highest density of attacks took place in 2007 and the type of attacks were explosions. Lowest number of attacks happen in the form of Kidnappings alone.

# Heat map
plot2 <- drop_na(df, `ATTACK TYPE`) %>% count(YEAR, `ATTACK TYPE`) %>% rename(Count = n) %>% mutate(`ATTACK TYPE` = reorder(`ATTACK TYPE`, Count)) %>% plot_ly(x = ~YEAR, y = ~`ATTACK TYPE`, z = ~Count, type = "heatmap")

plot2 <- plot2 %>% layout(title = "Terrorist Attacks time series by Type", yaxis = list(title = "Count"))
 
plot2

#Stacked Bar Chart
plot3 <- drop_na(df, `ATTACK TYPE`) %>% count(YEAR, `ATTACK TYPE`) %>% rename(Count = n) %>% ggplot(aes(YEAR, Count)) + geom_bar(aes(fill = `ATTACK TYPE`), stat = "identity") + scale_fill_brewer(palette = "Paired") + labs(title = "Terrorist Attacks time series by Type") + theme_light()
  
ggplotly(plot3)

The Plot above uses data similar to the previous plot but displays it in the form of a Stacked bar chart. The highest number of attacks took place in 2006 with the number being greater than 600. The split of the attack types can be seen as you hover over the plots along with the count and year. The required attack type can specifically be displayed from the legend on the right.

plot <- drop_na(df, `ATTACK TYPE`) %>% group_by(MONTH, `ATTACK TYPE`) %>% summarise(Deaths = sum(DEAD), Injured = sum(INJURED), Count = n()) %>% mutate(`ATTACK TYPE` = reorder(`ATTACK TYPE`, Count)) %>% plot_ly(hovertype = 'text', x = ~MONTH, y = ~`ATTACK TYPE`, z = ~Count, type = "heatmap", text = ~paste('Injured: ', Injured, '\nDeaths: ', Deaths))
`summarise()` has grouped output by 'MONTH'. You can override using the `.groups` argument.
plot <- plot %>% layout(title = "Terrorist Attacks time series by Type", xaxis = list(ticktext = Month_names, tickvals = Month_numbers, tickmode = "array"), yaxis = list(title = "Count"))
 
plot
Warning: 'heatmap' objects don't have these attributes: 'hovertype'
Valid attributes include:
'autocolorscale', 'coloraxis', 'colorbar', 'colorscale', 'connectgaps', 'customdata', 'customdatasrc', 'dx', 'dy', 'hoverinfo', 'hoverinfosrc', 'hoverlabel', 'hoverongaps', 'hovertemplate', 'hovertemplatesrc', 'hovertext', 'hovertextsrc', 'ids', 'idssrc', 'legendgroup', 'legendgrouptitle', 'legendrank', 'meta', 'metasrc', 'name', 'opacity', 'reversescale', 'showlegend', 'showscale', 'stream', 'text', 'textsrc', 'transforms', 'transpose', 'type', 'uid', 'uirevision', 'visible', 'x', 'x0', 'xaxis', 'xcalendar', 'xgap', 'xhoverformat', 'xperiod', 'xperiod0', 'xperiodalignment', 'xsrc', 'xtype', 'y', 'y0', 'yaxis', 'ycalendar', 'ygap', 'yhoverformat', 'yperiod', 'yperiod0', 'yperiodalignment', 'ysrc', 'ytype', 'z', 'zauto', 'zhoverformat', 'zmax', 'zmid', 'zmin', 'zsmooth', 'zsrc', 'key', 'set', 'frame', 'transforms', '_isNestedKey', '_isSimpleKey', '_isGraticule', '_bbox'

Warning: 'heatmap' objects don't have these attributes: 'hovertype'
Valid attributes include:
'autocolorscale', 'coloraxis', 'colorbar', 'colorscale', 'connectgaps', 'customdata', 'customdatasrc', 'dx', 'dy', 'hoverinfo', 'hoverinfosrc', 'hoverlabel', 'hoverongaps', 'hovertemplate', 'hovertemplatesrc', 'hovertext', 'hovertextsrc', 'ids', 'idssrc', 'legendgroup', 'legendgrouptitle', 'legendrank', 'meta', 'metasrc', 'name', 'opacity', 'reversescale', 'showlegend', 'showscale', 'stream', 'text', 'textsrc', 'transforms', 'transpose', 'type', 'uid', 'uirevision', 'visible', 'x', 'x0', 'xaxis', 'xcalendar', 'xgap', 'xhoverformat', 'xperiod', 'xperiod0', 'xperiodalignment', 'xsrc', 'xtype', 'y', 'y0', 'yaxis', 'ycalendar', 'ygap', 'yhoverformat', 'yperiod', 'yperiod0', 'yperiodalignment', 'ysrc', 'ytype', 'z', 'zauto', 'zhoverformat', 'zmax', 'zmid', 'zmin', 'zsmooth', 'zsrc', 'key', 'set', 'frame', 'transforms', '_isNestedKey', '_isSimpleKey', '_isGraticule', '_bbox'

The above heatmap plots the type of attacks along with the months of the year. On hovering the number of attacks, Deaths and injuries can be tallied. Highest frequency of deaths is in July and is caused by explosions.

# Stacked Bar Chart
r <- count(df, YEAR, COUNTRY, sort = TRUE)
r <- r %>% filter(n > 20) %>% rename(Count = n)
plot4 <- r %>% ggplot(aes(YEAR, Count)) + geom_bar(aes(fill = COUNTRY), stat = "identity") + scale_fill_brewer(palette = "Paired") + labs(title = "Overall frequency of Countries' Terrorist Attacks (more than 20 in a year)") + theme_light()

ggplotly(plot4)

The above plot uses stacked bar charts to count the number of attacks that take place in different countries in different years with the minimum number of attacks being 20. In 2006 more than 589 attacks took place in Iraq, the highest recorded.

# Violin Plot
t <- count(df, COUNTRY, sort = TRUE)[1:10,]
new_df <- merge(df, t, by = "COUNTRY", all = FALSE)
plot5 <- new_df %>% ggplot(aes(COUNTRY, YEAR)) + geom_violin(fill = "firebrick2", color = "firebrick2") + coord_flip() + labs(title = "Visible surges at top 10 countries with most attacks") + theme_light()
  
ggplotly(plot5)

The above violin plot depicts the top 10 countries based on attacks and the years in which there were great surges or increased number of attacks. From the plot we can say that between 1995 and 2010 there was an increase in the number of attacks throughout the world.

map(database = "world")
points(x = df$LONGITUDE, y = df$LATITUDE, col = 'red', pch = 19, cex = .5)

The above plot uses the world map to plot the coordinates of attacks with red points.There is a greater number of attacks taking place around Europe and Asia.

world <- map("world", fill = T, plot = F)
new_df$COUNTRY <- str_replace(new_df$COUNTRY, "United Kingdom", "UK:Great Britain")
new_df$COUNTRY <- str_replace(new_df$COUNTRY, "United States", "USA")

leaflet_map <- function(data, map_obj){
  map_obj$dataf <- left_join(data.frame(names = world$names, stringsAsFactors = F), data, by = c("names" = names(data)[1]))
  pal <- colorNumeric("YlOrRd", domain = map_obj$dataf[[3]], na.color = "white")
  strings <- sprintf(
    paste(
      "<strong>%s</strong><br/>", names(map_obj$dataf)[4], ifelse(is.numeric(map_obj$dataf[[4]]), ": %g ", ": %s "),
      paste("<br/>", names(map_obj$dataf)[3], ifelse(is.numeric(map_obj$dataf[[3]]), ": %g ", ": %s ")),
      paste("<br/>", names(map_obj$dataf)[2], ifelse(is.numeric(map_obj$dataf[[2]]), ": %g ", ": %s "))),
    map_obj$dataf[[1]], map_obj$dataf[[4]], map_obj$dataf[[3]], map_obj$dataf[[2]])
  labels <- strings %>% lapply(htmltools::HTML)
  m <- leaflet(map_obj) %>% addTiles()
  m <- m %>% addPolygons(
    fillColor = ~pal(dataf[[3]]),
    weight = 2,
    opacity = 1,
    color = "white",
    dashArray = "3",
    fillOpacity = 0.7,
    highlight = highlightOptions(
      weight = 5,
      color = "#666",
      dashArray = "",
      fillOpacity = 0.7,
      bringToFront = TRUE, stroke = 1),
    label = labels
    )
  m <- m %>%
    addLegend("bottomright", pal = pal, values = ~dataf[[3]],
    title = names(map_obj$dataf)[3],
    opacity = 1)
  return(m)
}
worldmap <- leaflet() %>% setView(lng = 0,lat = 0, zoom = 1) %>% addTiles()
country_data <- df %>% group_by(COUNTRY) %>% summarise(Deaths = sum(DEAD), Injured = sum(INJURED), Events = n()) %>% arrange(order(COUNTRY)) %>% rename(names = COUNTRY)
leaflet_map(country_data, world)

A proper functional map which is coloured based on the number of Injured persons for all attacks in the dataset. On hovering you can also get information such as deaths, events and injuries for each marked country. Iraq being red seems to have to most number of people getting injured due to attacks.

new_df$DECADE <- sapply(new_df$YEAR, function(x) {
  ifelse(x>=2020, "8) 2020s", 
         ifelse(x>=2010,"7) 2010s",
                ifelse(x>=2000,"6) 2000s",
                       ifelse(x>=1990,"4) 1990s",
                              ifelse(x>=1980,"3) 1980s",
                                     ifelse(x>=1970,"2) 1970s",
                                            "1) 1960s"))))))
})

plot_ly(new_df, hoverinfo = 'text', x = ~DEAD, y = ~INJURED, frame = ~DECADE, color = ~'red', colors = c('red'), alpha = 0.9, text = ~paste('Country: ', COUNTRY, '\nRegion: ', REGION, '\nDate: ', DATE, '\nPerpetrator: ', PERPETRATOR, '\nInjured : ', INJURED, '\nFatalities : ', DEAD)) %>% layout(title = "Animated History of incidents by Year", xaxis = list(title = "Deaths"), yaxis = list(title = "Injured"), showlegend = F) %>% animation_opts(1500, redraw = FALSE)
No trace type specified:
  Based on info supplied, a 'scatter' trace seems appropriate.
  Read more about this trace type -> https://plotly.com/r/reference/#scatter
No scatter mode specifed:
  Setting the mode to markers
  Read more about this attribute -> https://plotly.com/r/reference/#scatter-mode
No trace type specified:
  Based on info supplied, a 'scatter' trace seems appropriate.
  Read more about this trace type -> https://plotly.com/r/reference/#scatter
No scatter mode specifed:
  Setting the mode to markers
  Read more about this attribute -> https://plotly.com/r/reference/#scatter-mode

This is an animated scatterplot that allows us to compare the number of deaths with the number of injuries and manipulate it accordingly with the years. Between 2000 and 2010 the number of deaths increased as compared to other years.

LS0tDQp0aXRsZTogIkdsb2JhbCBUZXJyb3Jpc20iDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkocGxvdGx5KQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkobGVhZmxldCkNCmxpYnJhcnkobWFwcykNCmRmIDwtIHJlYWRfY3N2KCdrbGFwZXllLWdsb2JhbC10ZXJyb3Jpc20uY3N2JykNCmRmIDwtIGRyb3BfbmEoZGYsIElOSlVSRUQpDQpkZiA8LSBkcm9wX25hKGRmLCBERUFEKQ0KaGVhZChkZikNCmRpbShkZikNCg0KTW9udGhfbmFtZXMgPSBsaXN0KCJKQU4iLCAiRkVCIiwgIk1BUiIsICJBUFIiLCAiTUFZIiwgIkpVTiIsICJKVUwiLCAiQVVHIiwgIlNFUCIsICJPQ1QiLCAiTk9WIiwgIkRFQyIpDQpNb250aF9udW1iZXJzID0gbGlzdCgxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyKQ0KDQpkZiRZRUFSIDwtIGFzLm51bWVyaWMoZm9ybWF0KGRmJERBVEUsICIlWSIpKQ0KZGYkTU9OVEggPC0gYXMubnVtZXJpYyhmb3JtYXQoZGYkREFURSwgIiVtIikpDQpkZiREQVkgPC0gYXMubnVtZXJpYyhmb3JtYXQoZGYkREFURSwgIiVkIikpDQoNCmNsYXNzKGRmJENPT1JESU5BVEVTKQ0KZGYgPC0gZGYgJT4lIHNlcGFyYXRlKENPT1JESU5BVEVTLCBjKCJMQVRJVFVERSIsICJMT05HSVRVREUiKSwgc2VwID0gIiwiKQ0KYGBgDQpgYGB7cn0NCnBsb3QxIDwtIGRmICU+JSBjb3VudChZRUFSKSAlPiUgcmVuYW1lKENvdW50ID0gbikgJT4lIGdncGxvdChhZXMoWUVBUiwgQ291bnQpKSArIGdlb21fbGluZShjb2xvciA9ICJmaXJlYnJpY2syIikgKyBnZW9tX3BvaW50KGNvbG9yID0gImZpcmVicmljazIiKSArIGxhYnModGl0bGUgPSAiTnVtYmVyIG9mIHRlcnJvcmlzdCBhdGFja3MgYnkgeWVhciIpICsgdGhlbWVfbGlnaHQoKQ0KDQpnZ3Bsb3RseShwbG90MSkNCmBgYA0KVGhlIFBsb3QgZ2l2ZW4gYWJvdmUgdXNlcyBnZ3Bsb3RseSB0byBpbnRlcmFjdGl2ZWx5IHBsb3QgdGhlIG51bWJlciBvZiB0ZXJyb3Jpc3QgYXR0YWNrcyB3aXRoIHRoZSB5ZWFycyB0aGF0IHRoZXkgdG9vayBwbGFjZSBpbi4gVGhlIHllYXIgMjAwNiBoYWQgdGhlIGhpZ2hlc3QgbnVtYmVyIG9mIHRlcnJvcmlzdCBhdHRhY2tzIHdpdGggdGhlIG51bWJlciBvZiBhdHRhY2tzIGJlaW5nIDkxNC4NCmBgYHtyfQ0KIyBIZWF0IG1hcA0KcGxvdDIgPC0gZHJvcF9uYShkZiwgYEFUVEFDSyBUWVBFYCkgJT4lIGNvdW50KFlFQVIsIGBBVFRBQ0sgVFlQRWApICU+JSByZW5hbWUoQ291bnQgPSBuKSAlPiUgbXV0YXRlKGBBVFRBQ0sgVFlQRWAgPSByZW9yZGVyKGBBVFRBQ0sgVFlQRWAsIENvdW50KSkgJT4lIHBsb3RfbHkoeCA9IH5ZRUFSLCB5ID0gfmBBVFRBQ0sgVFlQRWAsIHogPSB+Q291bnQsIHR5cGUgPSAiaGVhdG1hcCIpDQoNCnBsb3QyIDwtIHBsb3QyICU+JSBsYXlvdXQodGl0bGUgPSAiVGVycm9yaXN0IEF0dGFja3MgdGltZSBzZXJpZXMgYnkgVHlwZSIsIHlheGlzID0gbGlzdCh0aXRsZSA9ICJDb3VudCIpKQ0KIA0KcGxvdDINCmBgYA0KSW4gdGhlIGFib3ZlIHBsb3QgUGxvdGx5IGlzIHVzZWQgdG8gYWRkIGEgaGVhdCBtYXAgdGhhdCBkZXNjcmliZXMgdGhlIG51bWJlciBvZiBhdHRhY2tzLCB0aGUgdHlwZSBvZiBhdHRhY2tzIGFuZCB0aGUgeWVhcnMgaW4gd2hpY2ggdGhleSB0b29rIHBsYWNlLiBUaGUgaGlnaGVzdCBkZW5zaXR5IG9mIGF0dGFja3MgdG9vayBwbGFjZSBpbiAyMDA3IGFuZCB0aGUgdHlwZSBvZiBhdHRhY2tzIHdlcmUgZXhwbG9zaW9ucy4gTG93ZXN0IG51bWJlciBvZiBhdHRhY2tzIGhhcHBlbiBpbiB0aGUgZm9ybSBvZg0KS2lkbmFwcGluZ3MgYWxvbmUuDQpgYGB7cn0NCiNTdGFja2VkIEJhciBDaGFydA0KcGxvdDMgPC0gZHJvcF9uYShkZiwgYEFUVEFDSyBUWVBFYCkgJT4lIGNvdW50KFlFQVIsIGBBVFRBQ0sgVFlQRWApICU+JSByZW5hbWUoQ291bnQgPSBuKSAlPiUgZ2dwbG90KGFlcyhZRUFSLCBDb3VudCkpICsgZ2VvbV9iYXIoYWVzKGZpbGwgPSBgQVRUQUNLIFRZUEVgKSwgc3RhdCA9ICJpZGVudGl0eSIpICsgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJQYWlyZWQiKSArIGxhYnModGl0bGUgPSAiVGVycm9yaXN0IEF0dGFja3MgdGltZSBzZXJpZXMgYnkgVHlwZSIpICsgdGhlbWVfbGlnaHQoKQ0KICANCmdncGxvdGx5KHBsb3QzKQ0KYGBgDQpUaGUgUGxvdCBhYm92ZSB1c2VzIGRhdGEgc2ltaWxhciB0byB0aGUgcHJldmlvdXMgcGxvdCBidXQgZGlzcGxheXMgaXQgaW4gdGhlIGZvcm0gb2YgYSBTdGFja2VkIGJhciBjaGFydC4gVGhlIGhpZ2hlc3QgbnVtYmVyIG9mIGF0dGFja3MgdG9vayBwbGFjZSBpbiAyMDA2IHdpdGggdGhlIG51bWJlciBiZWluZyBncmVhdGVyIHRoYW4gNjAwLiBUaGUgc3BsaXQgb2YgdGhlIGF0dGFjayB0eXBlcyBjYW4gYmUgc2VlbiBhcyB5b3UgaG92ZXIgb3ZlciB0aGUgcGxvdHMgYWxvbmcgd2l0aCB0aGUgY291bnQgYW5kIHllYXIuIFRoZSByZXF1aXJlZCBhdHRhY2sgdHlwZSBjYW4gc3BlY2lmaWNhbGx5IGJlIGRpc3BsYXllZCBmcm9tIHRoZSBsZWdlbmQgb24gdGhlIHJpZ2h0Lg0KYGBgIHtyfQ0KcGxvdCA8LSBkcm9wX25hKGRmLCBgQVRUQUNLIFRZUEVgKSAlPiUgZ3JvdXBfYnkoTU9OVEgsIGBBVFRBQ0sgVFlQRWApICU+JSBzdW1tYXJpc2UoRGVhdGhzID0gc3VtKERFQUQpLCBJbmp1cmVkID0gc3VtKElOSlVSRUQpLCBDb3VudCA9IG4oKSkgJT4lIG11dGF0ZShgQVRUQUNLIFRZUEVgID0gcmVvcmRlcihgQVRUQUNLIFRZUEVgLCBDb3VudCkpICU+JSBwbG90X2x5KGhvdmVydHlwZSA9ICd0ZXh0JywgeCA9IH5NT05USCwgeSA9IH5gQVRUQUNLIFRZUEVgLCB6ID0gfkNvdW50LCB0eXBlID0gImhlYXRtYXAiLCB0ZXh0ID0gfnBhc3RlKCdJbmp1cmVkOiAnLCBJbmp1cmVkLCAnXG5EZWF0aHM6ICcsIERlYXRocykpDQoNCnBsb3QgPC0gcGxvdCAlPiUgbGF5b3V0KHRpdGxlID0gIlRlcnJvcmlzdCBBdHRhY2tzIHRpbWUgc2VyaWVzIGJ5IFR5cGUiLCB4YXhpcyA9IGxpc3QodGlja3RleHQgPSBNb250aF9uYW1lcywgdGlja3ZhbHMgPSBNb250aF9udW1iZXJzLCB0aWNrbW9kZSA9ICJhcnJheSIpLCB5YXhpcyA9IGxpc3QodGl0bGUgPSAiQ291bnQiKSkNCiANCnBsb3QNCmBgYA0KVGhlIGFib3ZlIGhlYXRtYXAgcGxvdHMgdGhlIHR5cGUgb2YgYXR0YWNrcyBhbG9uZyB3aXRoIHRoZSBtb250aHMgb2YgdGhlIHllYXIuIE9uIGhvdmVyaW5nIHRoZSBudW1iZXIgb2YgYXR0YWNrcywgRGVhdGhzIGFuZCBpbmp1cmllcyBjYW4gYmUgdGFsbGllZC4gSGlnaGVzdCBmcmVxdWVuY3kgb2YgZGVhdGhzIGlzIGluIEp1bHkgYW5kIGlzIGNhdXNlZCBieSBleHBsb3Npb25zLg0KYGBge3J9DQojIFN0YWNrZWQgQmFyIENoYXJ0DQpyIDwtIGNvdW50KGRmLCBZRUFSLCBDT1VOVFJZLCBzb3J0ID0gVFJVRSkNCnIgPC0gciAlPiUgZmlsdGVyKG4gPiAyMCkgJT4lIHJlbmFtZShDb3VudCA9IG4pDQpwbG90NCA8LSByICU+JSBnZ3Bsb3QoYWVzKFlFQVIsIENvdW50KSkgKyBnZW9tX2JhcihhZXMoZmlsbCA9IENPVU5UUlkpLCBzdGF0ID0gImlkZW50aXR5IikgKyBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlBhaXJlZCIpICsgbGFicyh0aXRsZSA9ICJPdmVyYWxsIGZyZXF1ZW5jeSBvZiBDb3VudHJpZXMnIFRlcnJvcmlzdCBBdHRhY2tzIChtb3JlIHRoYW4gMjAgaW4gYSB5ZWFyKSIpICsgdGhlbWVfbGlnaHQoKQ0KDQpnZ3Bsb3RseShwbG90NCkNCmBgYA0KVGhlIGFib3ZlIHBsb3QgdXNlcyBzdGFja2VkIGJhciBjaGFydHMgdG8gY291bnQgdGhlIG51bWJlciBvZiBhdHRhY2tzIHRoYXQgdGFrZSBwbGFjZSBpbiBkaWZmZXJlbnQgY291bnRyaWVzIGluIGRpZmZlcmVudCB5ZWFycyB3aXRoIHRoZSBtaW5pbXVtIG51bWJlciBvZiBhdHRhY2tzIGJlaW5nIDIwLiBJbiAyMDA2IG1vcmUgdGhhbiA1ODkgYXR0YWNrcyB0b29rIHBsYWNlIGluIElyYXEsIHRoZSBoaWdoZXN0IHJlY29yZGVkLg0KYGBge3J9DQojIFZpb2xpbiBQbG90DQp0IDwtIGNvdW50KGRmLCBDT1VOVFJZLCBzb3J0ID0gVFJVRSlbMToxMCxdDQpuZXdfZGYgPC0gbWVyZ2UoZGYsIHQsIGJ5ID0gIkNPVU5UUlkiLCBhbGwgPSBGQUxTRSkNCnBsb3Q1IDwtIG5ld19kZiAlPiUgZ2dwbG90KGFlcyhDT1VOVFJZLCBZRUFSKSkgKyBnZW9tX3Zpb2xpbihmaWxsID0gImZpcmVicmljazIiLCBjb2xvciA9ICJmaXJlYnJpY2syIikgKyBjb29yZF9mbGlwKCkgKyBsYWJzKHRpdGxlID0gIlZpc2libGUgc3VyZ2VzIGF0IHRvcCAxMCBjb3VudHJpZXMgd2l0aCBtb3N0IGF0dGFja3MiKSArIHRoZW1lX2xpZ2h0KCkNCiAgDQpnZ3Bsb3RseShwbG90NSkNCmBgYA0KVGhlIGFib3ZlIHZpb2xpbiBwbG90IGRlcGljdHMgdGhlIHRvcCAxMCBjb3VudHJpZXMgYmFzZWQgb24gYXR0YWNrcyBhbmQgdGhlIHllYXJzIGluIHdoaWNoIHRoZXJlIHdlcmUgZ3JlYXQgc3VyZ2VzIG9yIGluY3JlYXNlZCBudW1iZXIgb2YgYXR0YWNrcy4gRnJvbSB0aGUgcGxvdCB3ZSBjYW4gc2F5IHRoYXQgYmV0d2VlbiAxOTk1IGFuZCAyMDEwIHRoZXJlIHdhcyBhbiBpbmNyZWFzZSBpbiB0aGUgbnVtYmVyIG9mIGF0dGFja3MgdGhyb3VnaG91dCB0aGUgd29ybGQuDQpgYGB7cn0NCm1hcChkYXRhYmFzZSA9ICJ3b3JsZCIpDQpwb2ludHMoeCA9IGRmJExPTkdJVFVERSwgeSA9IGRmJExBVElUVURFLCBjb2wgPSAncmVkJywgcGNoID0gMTksIGNleCA9IC41KQ0KYGBgDQpUaGUgYWJvdmUgcGxvdCB1c2VzIHRoZSB3b3JsZCBtYXAgdG8gcGxvdCB0aGUgY29vcmRpbmF0ZXMgb2YgYXR0YWNrcyB3aXRoIHJlZCBwb2ludHMuVGhlcmUgaXMgYSBncmVhdGVyIG51bWJlciBvZiBhdHRhY2tzIHRha2luZyBwbGFjZSBhcm91bmQgRXVyb3BlIGFuZCBBc2lhLg0KYGBge3J9DQp3b3JsZCA8LSBtYXAoIndvcmxkIiwgZmlsbCA9IFQsIHBsb3QgPSBGKQ0KbmV3X2RmJENPVU5UUlkgPC0gc3RyX3JlcGxhY2UobmV3X2RmJENPVU5UUlksICJVbml0ZWQgS2luZ2RvbSIsICJVSzpHcmVhdCBCcml0YWluIikNCm5ld19kZiRDT1VOVFJZIDwtIHN0cl9yZXBsYWNlKG5ld19kZiRDT1VOVFJZLCAiVW5pdGVkIFN0YXRlcyIsICJVU0EiKQ0KDQpsZWFmbGV0X21hcCA8LSBmdW5jdGlvbihkYXRhLCBtYXBfb2JqKXsNCiAgbWFwX29iaiRkYXRhZiA8LSBsZWZ0X2pvaW4oZGF0YS5mcmFtZShuYW1lcyA9IHdvcmxkJG5hbWVzLCBzdHJpbmdzQXNGYWN0b3JzID0gRiksIGRhdGEsIGJ5ID0gYygibmFtZXMiID0gbmFtZXMoZGF0YSlbMV0pKQ0KICBwYWwgPC0gY29sb3JOdW1lcmljKCJZbE9yUmQiLCBkb21haW4gPSBtYXBfb2JqJGRhdGFmW1szXV0sIG5hLmNvbG9yID0gIndoaXRlIikNCiAgc3RyaW5ncyA8LSBzcHJpbnRmKA0KICAgIHBhc3RlKA0KICAgICAgIjxzdHJvbmc+JXM8L3N0cm9uZz48YnIvPiIsIG5hbWVzKG1hcF9vYmokZGF0YWYpWzRdLCBpZmVsc2UoaXMubnVtZXJpYyhtYXBfb2JqJGRhdGFmW1s0XV0pLCAiOiAlZyAiLCAiOiAlcyAiKSwNCiAgICAgIHBhc3RlKCI8YnIvPiIsIG5hbWVzKG1hcF9vYmokZGF0YWYpWzNdLCBpZmVsc2UoaXMubnVtZXJpYyhtYXBfb2JqJGRhdGFmW1szXV0pLCAiOiAlZyAiLCAiOiAlcyAiKSksDQogICAgICBwYXN0ZSgiPGJyLz4iLCBuYW1lcyhtYXBfb2JqJGRhdGFmKVsyXSwgaWZlbHNlKGlzLm51bWVyaWMobWFwX29iaiRkYXRhZltbMl1dKSwgIjogJWcgIiwgIjogJXMgIikpKSwNCiAgICBtYXBfb2JqJGRhdGFmW1sxXV0sIG1hcF9vYmokZGF0YWZbWzRdXSwgbWFwX29iaiRkYXRhZltbM11dLCBtYXBfb2JqJGRhdGFmW1syXV0pDQogIGxhYmVscyA8LSBzdHJpbmdzICU+JSBsYXBwbHkoaHRtbHRvb2xzOjpIVE1MKQ0KICBtIDwtIGxlYWZsZXQobWFwX29iaikgJT4lIGFkZFRpbGVzKCkNCiAgbSA8LSBtICU+JSBhZGRQb2x5Z29ucygNCiAgICBmaWxsQ29sb3IgPSB+cGFsKGRhdGFmW1szXV0pLA0KICAgIHdlaWdodCA9IDIsDQogICAgb3BhY2l0eSA9IDEsDQogICAgY29sb3IgPSAid2hpdGUiLA0KICAgIGRhc2hBcnJheSA9ICIzIiwNCiAgICBmaWxsT3BhY2l0eSA9IDAuNywNCiAgICBoaWdobGlnaHQgPSBoaWdobGlnaHRPcHRpb25zKA0KICAgICAgd2VpZ2h0ID0gNSwNCiAgICAgIGNvbG9yID0gIiM2NjYiLA0KICAgICAgZGFzaEFycmF5ID0gIiIsDQogICAgICBmaWxsT3BhY2l0eSA9IDAuNywNCiAgICAgIGJyaW5nVG9Gcm9udCA9IFRSVUUsIHN0cm9rZSA9IDEpLA0KICAgIGxhYmVsID0gbGFiZWxzDQogICAgKQ0KICBtIDwtIG0gJT4lDQogICAgYWRkTGVnZW5kKCJib3R0b21yaWdodCIsIHBhbCA9IHBhbCwgdmFsdWVzID0gfmRhdGFmW1szXV0sDQogICAgdGl0bGUgPSBuYW1lcyhtYXBfb2JqJGRhdGFmKVszXSwNCiAgICBvcGFjaXR5ID0gMSkNCiAgcmV0dXJuKG0pDQp9DQpgYGANCmBgYHtyfQ0Kd29ybGRtYXAgPC0gbGVhZmxldCgpICU+JSBzZXRWaWV3KGxuZyA9IDAsbGF0ID0gMCwgem9vbSA9IDEpICU+JSBhZGRUaWxlcygpDQpjb3VudHJ5X2RhdGEgPC0gZGYgJT4lIGdyb3VwX2J5KENPVU5UUlkpICU+JSBzdW1tYXJpc2UoRGVhdGhzID0gc3VtKERFQUQpLCBJbmp1cmVkID0gc3VtKElOSlVSRUQpLCBFdmVudHMgPSBuKCkpICU+JSBhcnJhbmdlKG9yZGVyKENPVU5UUlkpKSAlPiUgcmVuYW1lKG5hbWVzID0gQ09VTlRSWSkNCmxlYWZsZXRfbWFwKGNvdW50cnlfZGF0YSwgd29ybGQpDQpgYGANCkEgcHJvcGVyIGZ1bmN0aW9uYWwgbWFwIHdoaWNoIGlzIGNvbG91cmVkIGJhc2VkIG9uIHRoZSBudW1iZXIgb2YgSW5qdXJlZCBwZXJzb25zIGZvciBhbGwgYXR0YWNrcyBpbiB0aGUgZGF0YXNldC4gT24gaG92ZXJpbmcgeW91IGNhbiBhbHNvIGdldCBpbmZvcm1hdGlvbiBzdWNoIGFzIGRlYXRocywgZXZlbnRzIGFuZCBpbmp1cmllcyBmb3IgZWFjaCBtYXJrZWQgY291bnRyeS4gSXJhcSBiZWluZyByZWQgc2VlbXMgdG8gaGF2ZSB0byBtb3N0IG51bWJlciBvZiBwZW9wbGUgZ2V0dGluZyBpbmp1cmVkIGR1ZSB0byBhdHRhY2tzLg0KYGBge3J9DQpuZXdfZGYkREVDQURFIDwtIHNhcHBseShuZXdfZGYkWUVBUiwgZnVuY3Rpb24oeCkgew0KICBpZmVsc2UoeD49MjAyMCwgIjgpIDIwMjBzIiwgDQogICAgICAgICBpZmVsc2UoeD49MjAxMCwiNykgMjAxMHMiLA0KICAgICAgICAgICAgICAgIGlmZWxzZSh4Pj0yMDAwLCI2KSAyMDAwcyIsDQogICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh4Pj0xOTkwLCI0KSAxOTkwcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoeD49MTk4MCwiMykgMTk4MHMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh4Pj0xOTcwLCIyKSAxOTcwcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIxKSAxOTYwcyIpKSkpKSkNCn0pDQoNCnBsb3RfbHkobmV3X2RmLCBob3ZlcmluZm8gPSAndGV4dCcsIHggPSB+REVBRCwgeSA9IH5JTkpVUkVELCBmcmFtZSA9IH5ERUNBREUsIGNvbG9yID0gfidyZWQnLCBjb2xvcnMgPSBjKCdyZWQnKSwgYWxwaGEgPSAwLjksIHRleHQgPSB+cGFzdGUoJ0NvdW50cnk6ICcsIENPVU5UUlksICdcblJlZ2lvbjogJywgUkVHSU9OLCAnXG5EYXRlOiAnLCBEQVRFLCAnXG5QZXJwZXRyYXRvcjogJywgUEVSUEVUUkFUT1IsICdcbkluanVyZWQgOiAnLCBJTkpVUkVELCAnXG5GYXRhbGl0aWVzIDogJywgREVBRCkpICU+JSBsYXlvdXQodGl0bGUgPSAiQW5pbWF0ZWQgSGlzdG9yeSBvZiBpbmNpZGVudHMgYnkgWWVhciIsIHhheGlzID0gbGlzdCh0aXRsZSA9ICJEZWF0aHMiKSwgeWF4aXMgPSBsaXN0KHRpdGxlID0gIkluanVyZWQiKSwgc2hvd2xlZ2VuZCA9IEYpICU+JSBhbmltYXRpb25fb3B0cygxNTAwLCByZWRyYXcgPSBGQUxTRSkNCmBgYA0KVGhpcyBpcyBhbiBhbmltYXRlZCBzY2F0dGVycGxvdCB0aGF0IGFsbG93cyB1cyB0byBjb21wYXJlIHRoZSBudW1iZXIgb2YgZGVhdGhzIHdpdGggdGhlIG51bWJlciBvZiBpbmp1cmllcyBhbmQgbWFuaXB1bGF0ZSBpdCBhY2NvcmRpbmdseSB3aXRoIHRoZSB5ZWFycy4gQmV0d2VlbiAyMDAwIGFuZCAyMDEwIHRoZSBudW1iZXIgb2YgZGVhdGhzIGluY3JlYXNlZCBhcyBjb21wYXJlZCB0byBvdGhlciB5ZWFycy4=